using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace SomeGame
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteFont battleFont;
        KeyboardState keyboard;

        Person player;
        Person enemy;

        //for player
        bool key1IsPressed = false;
        bool key1WasPressed = false;
        bool key2IsPressed = false;
        bool key2WasPressed = false;
        bool keyZIsPressed = false;
        bool keyZWasPressed = false;
        bool keyXIsPressed = false;
        bool keyXWasPressed = false;
        bool key3IsPressed = false;
        bool key3WasPressed = false;
        bool key4IsPressed = false;
        bool key4WasPressed = false;
        bool playerCanCast = true;

        bool keyUIsPressed = false;
        bool keyUWasPressed = false;
        bool keyIIsPressed = false;
        bool keyIWasPressed = false;
        bool keyOIsPressed = false;
        bool keyOWasPressed = false;
        bool keyPIsPressed = false;
        bool keyPWasPressed = false;
        bool keyKIsPressed = false;
        bool keyKWasPressed = false;
        bool keyLIsPressed = false;
        bool keyLWasPressed = false;
        bool enemyCanCast = true;

        bool isGameOver = false;

        List<Actor> prizes = new List<Actor>();
        List<Actor> obstacles = new List<Actor>();
        List<Vector2> prizeLocs = new List<Vector2>();
        List<Vector2> obstacleLocs = new List<Vector2>();

        //sounds
        SoundEffect playerHit;
        SoundEffect playerMagic;
        SoundEffect playerHurt;
        SoundEffect enemyHit;
        SoundEffect enemyMagic;
        SoundEffect enemyHurt;
        SoundEffect buy;
        SoundEffect manaReg;
        SoundEffect hpReg;

        Texture2D playerImg;
        Texture2D enemyImg;

        Texture2D obstacleImg;

        //Actor obstacle1;
        //Actor obstacle2;
        //Actor obstacle3;
        //Actor obstacle4;
        //Actor obstacle5;

        Texture2D prizeImg;

        //Actor prize1;
        //Actor prize2;
        //Actor prize3;
        //Actor prize4;
        //Actor prize5;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
 
            spriteBatch = new SpriteBatch(GraphicsDevice);
            

            player = new Person(this, 100, 50, 5, 25, 8, 3, 30,true);
            player.Initialize(Vector2.Zero, new Rectangle(0, 0, 50, 50), Color.White,
                              Vector2.Zero, new Vector2(1, 1), 0.0f);

            enemy = new Person(this, 100, 50, 8, 25, 5, 3, 20,false);
            enemy.Initialize(Vector2.Zero, new Rectangle(0, 0, 50, 50), Color.White,
                             Vector2.Zero, new Vector2(1, 1), 0.0f);

            for (int i = 0; i < 5; i++)
            {
                obstacles.Add(new Actor(this));
                Components.Add(obstacles[i]);
            }

            for (int i = 0; i < 5; i++)
            {
                prizes.Add(new Actor(this));
                Components.Add(prizes[i]);
            }

            prizeLocs.Add(new Vector2(300, 300));
            prizeLocs.Add(new Vector2(20, 400));
            prizeLocs.Add(new Vector2(500, 150));
            prizeLocs.Add(new Vector2(700, 253));
            prizeLocs.Add(new Vector2(220, 100));

            obstacleLocs.Add(new Vector2(75, 68));
            obstacleLocs.Add(new Vector2(200, 300));
            obstacleLocs.Add(new Vector2(470, 400));
            obstacleLocs.Add(new Vector2(340, 12));
            obstacleLocs.Add(new Vector2(667, 146));

            for (int i = 0; i < 5; i++)
            {
                obstacles[i].Initialize(obstacleLocs[i], new Rectangle(0, 0, 50, 50), Color.White,
                                     Vector2.Zero, new Vector2(1, 1), 0.0f);
            }

            //obstacle1 = new Actor(this);
            //obstacle1.Initialize(new Vector2(75,68), new Rectangle(0, 0, 50, 50), Color.White,
            //                 Vector2.Zero, new Vector2(1, 1), 0.0f);
            //obstacle2 = new Actor(this);
            //obstacle2.Initialize(new Vector2(200, 300), new Rectangle(0, 0, 50, 50), Color.White,
            //                 Vector2.Zero, new Vector2(1, 1), 0.0f);
            //obstacle3 = new Actor(this);
            //obstacle3.Initialize(new Vector2(470, 400), new Rectangle(0, 0, 50, 50), Color.White,
            //                 Vector2.Zero, new Vector2(1, 1), 0.0f);
            //obstacle4 = new Actor(this);
            //obstacle4.Initialize(new Vector2(340, 12), new Rectangle(0, 0, 50, 50), Color.White,
            //                 Vector2.Zero, new Vector2(1, 1), 0.0f);
            //obstacle5 = new Actor(this);
            //obstacle5.Initialize(new Vector2(667, 146), new Rectangle(0, 0, 50, 50), Color.White,
            //                 Vector2.Zero, new Vector2(1, 1), 0.0f);



            for (int i = 0; i < 5; i++)
            {
                prizes[i].Initialize(prizeLocs[i], new Rectangle(0, 0, 50, 50), Color.White,
                                     Vector2.Zero, new Vector2(1, 1), 0.0f);
            }


            //prize1 = new Actor(this);
            //prize1.Initialize(new Vector2(300, 300), new Rectangle(0, 0, 50, 50), Color.White,
            //                 Vector2.Zero, new Vector2(1, 1), 0.0f);
            //prize2 = new Actor(this);
            //prize2.Initialize(new Vector2(20, 400), new Rectangle(0, 0, 50, 50), Color.White,
            //                 Vector2.Zero, new Vector2(1, 1), 0.0f);
            //prize3 = new Actor(this);
            //prize3.Initialize(new Vector2(500, 150), new Rectangle(0, 0, 50, 50), Color.White,
            //                 Vector2.Zero, new Vector2(1, 1), 0.0f);
            //prize4 = new Actor(this);
            //prize4.Initialize(new Vector2(700, 253), new Rectangle(0, 0, 50, 50), Color.White,
            //                 Vector2.Zero, new Vector2(1, 1), 0.0f);
            //prize5 = new Actor(this);
            //prize5.Initialize(new Vector2(220, 100), new Rectangle(0, 0, 50, 50), Color.White,
            //                 Vector2.Zero, new Vector2(1, 1), 0.0f);

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            
            battleFont = Content.Load<SpriteFont>("BattleFont");

            playerHit = Content.Load<SoundEffect>("fire");
            playerMagic = Content.Load<SoundEffect>("UI_Misc07");
            playerHurt = Content.Load<SoundEffect>("Body_Hit_08");
            enemyHit = Content.Load<SoundEffect>("Minigunfire");
            enemyMagic = Content.Load<SoundEffect>("short_whoosh_02");
            enemyHurt = Content.Load<SoundEffect>("Body_Hit_17");
            buy = Content.Load<SoundEffect>("UI_Misc15");
            manaReg = Content.Load<SoundEffect>("long_whoosh_00");
            hpReg = Content.Load<SoundEffect>("med_whoosh_02");

            playerImg = Content.Load<Texture2D>("tastyplayer");
            enemyImg = Content.Load<Texture2D>("biscuit");

            player.LoadContent(spriteBatch, ref playerImg);
            enemy.LoadContent(spriteBatch, ref enemyImg);

            obstacleImg = Content.Load<Texture2D>("enemymouth");
            prizeImg = Content.Load<Texture2D>("tea");

            foreach (Actor obstacle in obstacles)
            {
                obstacle.LoadContent(spriteBatch, ref obstacleImg);
            }
            //obstacle1.LoadContent(spriteBatch, ref obstacleImg);
            //obstacle2.LoadContent(spriteBatch, ref obstacleImg);
            //obstacle3.LoadContent(spriteBatch, ref obstacleImg);
            //obstacle4.LoadContent(spriteBatch, ref obstacleImg);
            //obstacle5.LoadContent(spriteBatch, ref obstacleImg);

            foreach ( Actor prize in prizes)
            {
                prize.LoadContent(spriteBatch, ref prizeImg);
            }
            //prize1.LoadContent(spriteBatch, ref prizeImg);
            //prize2.LoadContent(spriteBatch, ref prizeImg);
            //prize3.LoadContent(spriteBatch, ref prizeImg);
            //prize4.LoadContent(spriteBatch, ref prizeImg);
            //prize5.LoadContent(spriteBatch, ref prizeImg);

            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            HandleInput();

            foreach (Actor obstacle in obstacles)
            {
                if (player.Colliding(obstacle) || enemy.Colliding(obstacle))
                {
                    obstacle.Dispose();
                }
            }
            foreach (Actor prize in prizes)
            {
                if (player.Colliding(prize) || enemy.Colliding(prize))
                {
                    prize.Dispose();
                }

            }

            // TODO: Add your update logic here

            base.Update(gameTime);
        }


        public void HandleInput()
        {

            keyboard = Keyboard.GetState();
            key1IsPressed = keyboard.IsKeyDown(Keys.D1);
            key2IsPressed = keyboard.IsKeyDown(Keys.D2);
            key4IsPressed = keyboard.IsKeyDown(Keys.D4);
            keyZIsPressed = keyboard.IsKeyDown(Keys.Z);
            keyXIsPressed = keyboard.IsKeyDown(Keys.X);

            keyUIsPressed = keyboard.IsKeyDown(Keys.U);
            keyIIsPressed = keyboard.IsKeyDown(Keys.I);
            keyPIsPressed = keyboard.IsKeyDown(Keys.P);
            keyKIsPressed = keyboard.IsKeyDown(Keys.K);
            keyLIsPressed = keyboard.IsKeyDown(Keys.L);

            //player attacks
            if (!key1IsPressed && key1WasPressed)
            {
                playerHit.Play(0.1f, 0.0f, 1.0f);
                enemy.Health = enemy.Health - player.Strength;
                enemyHurt.Play(1.0f, 0.0f, -1.0f);
            }
            key1WasPressed = key1IsPressed;

            //checks if player can use magic
            if ((player.Mana - player.Magic) < 0)
            {
                playerCanCast = false;
            }

            //player uses magic
            if (!key2IsPressed && key2WasPressed && (playerCanCast == true))
            {
                playerMagic.Play(1.0f, 0.0f, 1.0f);
                player.Mana = player.Mana - player.Magic;
                enemy.Health = enemy.Health - player.Magic;
                enemyHurt.Play(1.0f, 0.0f, -1.0f);
            }
            key2WasPressed = key2IsPressed;

            //player buys mana pot
            if ((player.Monies - 6) > 0)
            {
                if (!keyZIsPressed && keyZWasPressed)
                {
                    buy.Play(1.0f, 0.0f, 1.0f);
                    player.Monies = player.Monies - 6;
                    player.ManaPots = player.ManaPots + 1;
                }
                keyZWasPressed = keyZIsPressed;
            }

            //player uses mana pot
            if (playerCanCast == false)
            {
                
                key3IsPressed = keyboard.IsKeyDown(Keys.D3);
                if (!key3IsPressed && key3WasPressed && (player.ManaPots > 0))
                {
                    manaReg.Play(1.0f, 0.0f, 1.0f);
                    player.Mana = player.MaxMana;
                    player.ManaPots = player.ManaPots - 1;
                    playerCanCast = true;
                }
                key3WasPressed = key3IsPressed;
            }

            //player buys health pots
            if (!keyXIsPressed && keyXWasPressed && (player.Monies - 7) > 0)
            {
                buy.Play(1.0f, 0.0f, 1.0f);
                player.Monies = player.Monies - 7;
                player.HealthPots = player.HealthPots + 1;
            }
            keyXWasPressed = keyXIsPressed;

            //player uses health pots
            if (!key4IsPressed && key4WasPressed && player.HealthPots > 0)
            {
                hpReg.Play(1.0f, 0.0f, 1.0f);
                if (player.Health + 50 > player.MaxHealth)
                {
                    player.Health = player.MaxHealth;
                    player.HealthPots = player.HealthPots - 1;
                }
                else
                {
                    player.Health = player.Health + 50;
                    player.HealthPots = player.HealthPots - 1;
                }
            }
            key4WasPressed = key4IsPressed;

            //enemy attacks
            if (!keyUIsPressed && keyUWasPressed)
            {
                enemyHit.Play(0.2f, 0.0f, -1.0f);
                player.Health = player.Health - enemy.Strength;
                playerHurt.Play(1.0f, 0.0f, 1.0f);
            }
            keyUWasPressed = keyUIsPressed;

            //checks if enemy can use magic
            if ((enemy.Mana - enemy.Magic) < 0)
            {
                enemyCanCast = false;
            }

            //enemy uses magic
            if (!keyIIsPressed && keyIWasPressed && (enemyCanCast == true))
            {
                enemyMagic.Play(1.0f, 0.0f, -1.0f);
                enemy.Mana = enemy.Mana - enemy.Magic;
                player.Health = player.Health - enemy.Magic;
                playerHurt.Play(1.0f, 0.0f, 1.0f);
            }
            keyIWasPressed = keyIIsPressed;

            //enemy buys mana pot
            if ((enemy.Monies - 6) > 0)
            {
                
                if (!keyKIsPressed && keyKWasPressed)
                {
                    buy.Play(1.0f, 0.0f, -1.0f);
                    enemy.Monies = enemy.Monies - 6;
                    enemy.ManaPots = enemy.ManaPots + 1;
                }
                keyKWasPressed = keyKIsPressed;
            }

            //enemy uses mana pot
            if (enemyCanCast == false)
            {
                keyOIsPressed = keyboard.IsKeyDown(Keys.O);
                if (!keyOIsPressed && keyOWasPressed && (enemy.ManaPots > 0))
                {
                    manaReg.Play(1.0f, 0.0f, -1.0f);
                    enemy.Mana = enemy.MaxMana;
                    enemy.ManaPots = enemy.ManaPots - 1;
                    enemyCanCast = true;
                }
                keyOWasPressed = keyOIsPressed;
            }

            //enemy buys health pots
            if (!keyLIsPressed && keyLWasPressed && (enemy.Monies - 7) > 0)
            {
                buy.Play(1.0f, 0.0f, -1.0f);
                enemy.Monies = enemy.Monies - 7;
                enemy.HealthPots = enemy.HealthPots + 1;
            }
            keyLWasPressed = keyLIsPressed;

            //enemy uses health pots
            if (!keyPIsPressed && keyPWasPressed && enemy.HealthPots > 0)
            {
                hpReg.Play(1.0f, 0.0f, -1.0f);
                if (enemy.Health + 50 > enemy.MaxHealth)
                {
                    enemy.Health = enemy.MaxHealth;
                    enemy.HealthPots = enemy.HealthPots - 1;
                }
                else
                {
                    enemy.Health = enemy.Health + 50;
                    enemy.HealthPots = enemy.HealthPots - 1;
                }
            }
            keyPWasPressed = keyPIsPressed;

            //enemy dies & player gains monies
            if (enemy.Health <= 0)
            {
                enemy.Lives = enemy.Lives - 1;
                enemy.Health = 100;
                player.Monies = player.Monies + 10;
            }

            //player dies & enemy gains monies
            if (player.Health <= 0)
            {
                player.Lives = player.Lives - 1;
                player.Health = 100;
                enemy.Monies = enemy.Monies + 10;
            }

            //enemy loses all lives and game ends
            if (enemy.Lives < 0)
            {
                isGameOver = true;
                enemy.Status = 1;
            }

            //player loses all lives and game ends
            if (player.Lives < 0)
            {
                isGameOver = true;
                player.Status = 1;
            }
        }
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            //foreach (Actor prize in prizes)
            //{
            //    prize.Draw(gameTime);
            //}

            //foreach (Actor obstacle in obstacles)
            //{
            //    obstacle.Draw(gameTime);
            //}
            spriteBatch.Begin();

            if (isGameOver == false)
            {
                //spriteBatch.DrawString(battleFont, "My Stats- \nMy Health: " + player.Health + "\nMy Mana: " + player.Mana + "\nMy Strength: " + player.Strength + "\nMy Honor: " + player.Honor + "\nMy Magic: " + player.Magic + "\nMy Charisma: " + player.Charisma + "\nMy Lives: " + player.Lives + "\nMy Mana Pots: " + player.ManaPots + "\nMy Health Pots: " + player.HealthPots + "\nMy Monies: " + player.Monies, new Vector2(10, 10), Color.White);
                //spriteBatch.DrawString(battleFont, "Enemy Stats- \nHealth: " + enemy.Health + "\nMana: " + enemy.Mana + "\nStrength: " + enemy.Strength + "\nHonor: " + enemy.Honor + "\nMagic: " + enemy.Magic + "\nCharisma: " + enemy.Charisma + "\nLives: " + enemy.Lives + "\nMana Pots: " + enemy.ManaPots + "\nHealth Pots: " + enemy.HealthPots + "\nMonies: " + enemy.Monies, new Vector2(210, 10), Color.White);
            }
            else
            {
                if (enemy.Status == 1)
                {
                    spriteBatch.DrawString(battleFont, "GAME OVER \nYou Win!!", new Vector2(90, 90), Color.White);
                }
                else if (player.Status == 1)
                {
                    spriteBatch.DrawString(battleFont, "GAME OVER \nYou Lose", new Vector2(90, 90), Color.White);
                }
            }
            spriteBatch.End();
            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}
